#define ASM_FILE        1
#include "multiboot2.h"

/*  C symbol format. HAVE_ASM_USCORE is defined by configure. */
#ifdef HAVE_ASM_USCORE
# define EXT_C(sym)                     _ ## sym
#else
# define EXT_C(sym)                     sym
#endif

/*  The size of our stack (16KB). */
#define STACK_SIZE                      0x4000

/*  The flags for the Multiboot header. */
#ifdef __ELF__
# define AOUT_KLUDGE 0
#else
# define AOUT_KLUDGE MULTIBOOT_AOUT_KLUDGE
#endif
        
        .text

        .globl  start, _start
start:
_start:
        jmp     multiboot_entry

        /*  Align 64 bits boundary. */
        .align  8
        
        /*  Multiboot header. */
multiboot_header:
        /*  magic */
        .long   MULTIBOOT2_HEADER_MAGIC
        /*  ISA: i386 */
        .long   MULTIBOOT_ARCHITECTURE_I386
        /*  Header length. */
        .long   multiboot_header_end - multiboot_header
        /*  checksum */
        .long   -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 + (multiboot_header_end - multiboot_header))
#ifndef __ELF__
address_tag_start:      
        .short MULTIBOOT_HEADER_TAG_ADDRESS
        .short MULTIBOOT_HEADER_TAG_OPTIONAL
        .long address_tag_end - address_tag_start
        /*  header_addr */
        .long   multiboot_header
        /*  load_addr */
        .long   _start
        /*  load_end_addr */
        .long   _edata
        /*  bss_end_addr */
        .long   _end
address_tag_end:
entry_address_tag_start:        
        .short MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS
        .short MULTIBOOT_HEADER_TAG_OPTIONAL
        .long entry_address_tag_end - entry_address_tag_start
        /*  entry_addr */
        .long multiboot_entry
entry_address_tag_end:
#endif /*  __ELF__ */
framebuffer_tag_start:  
        .short MULTIBOOT_HEADER_TAG_FRAMEBUFFER
        .short MULTIBOOT_HEADER_TAG_OPTIONAL
        .long framebuffer_tag_end - framebuffer_tag_start
        .long 1024
        .long 768
        .long 32
        .long 0
framebuffer_tag_end:
        .short MULTIBOOT_HEADER_TAG_END
        .short 0
        .long 8
multiboot_header_end:
multiboot_entry:
        /*  Initialize the stack pointer. */
        movl    $(stack + STACK_SIZE), %esp

        /*  Reset EFLAGS. */
        pushl   $0
        popf

        /*  Push the pointer to the Multiboot information structure. */
        pushl   %ebx
        /*  Push the magic value. */
        pushl   %eax

        //进入64位模式


        /*  Now enter the C main function... */
        call    EXT_C(Start_Boot)
        
loop:   hlt
        jmp     loop

halt_message:
        .asciz  "Halted."

        /*  Our stack area. */
        .comm   stack, STACK_SIZE

            .section    .data
            .globl  GDT_Table

GDT_Table:
            .quad   0x0000000000000000                      /*0     NULL descriptor                 00*/
            .quad   0x0020980000000000                      /*1     KERNEL  Code    64-bit  Segment 08*/
            .quad   0x0000920000000000                      /*2     KERNEL  Data    64-bit  Segment 10*/
            .quad   0x0000000000000000                      /*3     USER    Code    32-bit  Segment 18*/
            .quad   0x0000000000000000                      /*4     USER    Data    32-bit  Segment 20*/
            .quad   0x0020f80000000000                      /*5     USER    Code    64-bit  Segment 28*/
            .quad   0x0000f20000000000                      /*6     USER    Data    64-bit  Segment 30*/
            .quad   0x00cf9a000000ffff                      /*7     KERNEL  Code    32-bit  Segment 38*/
            .quad   0x00cf92000000ffff                      /*8     KERNEL  Data    32-bit  Segment 40*/
            .fill   10,8,0
GDT_End:

GDT_POINTER:
GDT_LIMIT:  .word   GDT_End - GDT_Table - 1
GDT_BASE:   .quad   GDT_Table

            .globl  IDT_Table

IDT_Table:  .fill   512,    8,  0
IDT_End:

IDT_POINTER:
IDT_LIMIT:  .word   IDT_End - IDT_Table - 1
IDT_BASE:   .quad   IDT_Table

            .globl  TSS_Table

TSS_Table:  .fill   13,     8,  0
TSS_End:

TSS_POINTER:
TSS_LIMIT:  .word   TSS_End - TSS_Table - 1
TSS_BASE:   .quad   TSS_Table

